# 11์žฅ ์‹œํฌ๋ฆฟ

Assembled by GimunLee


# ์‹œํฌ๋ฆฟ ๊ฐœ๋…

  • ์‹œํฌ๋ฆฟ์€ ๋น„๋ฐ€๋ฒˆํ˜ธ, OAuth ํ† ๊ทผ, SSH ํ‚ค ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋“ค์„ ์ €์žฅํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉ
  • ์‹œํฌ๋ฆฟ์€ ์ปจํ…Œ์ด๋„ˆ ์•ˆ์— ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ๋ณ„๋„ ๋ณด๊ด€ํ–ˆ๋‹ค๊ฐ€ ์‹ค์ œ ํŒŒ๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ์˜ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ์ œ๊ณต
  • ์‹œํฌ๋ฆฟ์€ ๋‚ด์žฅ ์‹œํฌ๋ฆฟ๊ณผ ์‚ฌ์šฉ์ž ์ •์˜ ์‹œํฌ๋ฆฟ์œผ๋กœ ๊ตฌ๋ถ„
    • ๋‚ด์žฅ ์‹œํฌ๋ฆฟ: ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋Ÿฌ์Šคํ„ฐ ์•ˆ์—์„œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API์— ์ ‘๊ทผํ•  ๋•Œ ์‚ฌ์šฉ, ํด๋Ÿฌ์Šคํ„ฐ ์•ˆ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ServiceAccount๋ผ๋Š” ๊ณ„์ •์„ ์ƒ์„ฑํ•˜๋ฉด ์ž๋™์œผ๋กœ ๊ด€๋ จ ์‹œํฌ๋ฆฟ ์ƒ์„ฑํ•˜๊ณ  ์ด ์‹œํฌ๋ฆฟ์œผ๋กœ ํ—ˆ์šฉ๋œ API์— ์ ‘๊ทผ ๊ฐ€๋Šฅ
    • ์‚ฌ์šฉ์ž ์ •์˜ ์‹œํฌ๋ฆฟ: ์‚ฌ์šฉ์ž๊ฐ€ ๋งŒ๋“  ์‹œํฌ๋ฆฟ

# ๋ช…๋ น์œผ๋กœ ์‹œํฌ๋ฆฟ ๋งŒ๋“ค๊ธฐ

  1. ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์„ค์ •ํ•˜๋Š” ํŒŒ์ผ ์ƒ์„ฑ

    $ echo -n 'username' > ./username.txt
    $ echo -n 'password' > ./password.txt
    
  2. ์‹œํฌ๋ฆฟ ์ƒ์„ฑ // ์ž๋™์œผ๋กœ base64 ๋ฌธ์ž ์ธ์ฝ”๋”ฉ

    $ kubectl create secret generic user-pass-secret --from-file=./username.txt
    
  3. ์ƒ์„ฑํ•œ ์‹œํฌ๋ฆฟ ํ™•์ธ

    $ kubectl get secret user-pass-secret -o yaml
    
  4. ๋””์ฝ”๋”ฉํ•ด์„œ ํ™•์ธ

    $ echo {์ธ์ฝ”๋”ฉ๋œ๊ฐ’} | base64 --decode
    

# ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์‹œํฌ๋ฆฟ ๋งŒ๋“ค๊ธฐ

apiVersion: v1
kind: Secret
metadata:
  name: user-pass-yaml
type: Opaque # ๊ธฐ๋ณธ๊ฐ’
data:
  username: dXNlcm5hbWU=
  password: cGFzc3dvcmQ=
  • ์‹œํฌ๋ฆฟ ํƒ€์ž…
    • Opaque: ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ํ‚ค-๊ฐ’ ํ˜•์‹์œผ๋กœ ์ž„์˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Œ
    • kubernetes.io/service-account-token: ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ธ์ฆ ํ† ํฐ์„ ์ €์žฅํ•จ
    • kubernetes.io/dockerconfigjson: ๋„์ปค ์ €์žฅ์†Œ ์ธ์ฆ ์ •๋ณด๋ฅผ ์ €์žฅํ•จ
    • kubernetes.io/tls: TLS ์ธ์ฆ์„œ๋ฅผ ์ €์žฅํ•จ

# ์‹œํฌ๋ฆฟ ์‚ฌ์šฉํ•˜๊ธฐ

# ํŒŒ๋“œ์˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์‹œํฌ๋ฆฟ ์‚ฌ์šฉํ•˜๊ธฐ

apiVersion: apps/v1
kind: Deployment
metadata:
  name: secretapp
  labels:
    app: secretapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: secretapp
  template:
    metadata:
      labels:
        app: secretapp
    spec:
      containers:
      - name: testapp
        image: arisu1000/simple-container-app:latest
        ports:
        - containerPort: 8080
        env:
        - name: SECRET_USERNAME # ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์ด๋ฆ„ ์„ค์ •
          valueFrom: 
            secretKeyRef:
              name: user-pass-yaml # ์‹œํฌ๋ฆฟ์˜ ์ด๋ฆ„
              key: username # ํ‚ค ๊ฐ’
        - name: SECRET_PASSWORD
          valueFrom:
            secretKeyRef:
              name: user-pass-yaml
              key: password
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: secretapp
  name: secretapp-svc
  namespace: default
spec:
  ports:
  - nodePort: 30900
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: secretapp
  type: NodePort

# ๋ณผ๋ฅจ ํ˜•์‹์œผ๋กœ ํŒŒ๋“œ์— ์‹œํฌ๋ฆฟ ์ œ๊ณตํ•˜๊ธฐ

apiVersion: apps/v1
kind: Deployment
metadata:
  name: secretapp
  labels:
    app: secretapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: secretapp
  template:
    metadata:
      labels:
        app: secretapp
    spec:
      containers:
      - name: testapp
        image: arisu1000/simple-container-app:latest
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: volume-secret
          mountPath: "/etc/volume-secret" # ์‹œํฌ๋ฆฟ ์„ค์ • ๋‚ด์šฉ์„ ํŒŒ์ผ ํ˜•ํƒœ๋กœ ์ €์žฅ
          readOnly: true # ๋ณผ๋ฅจ์„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์‚ฌ์šฉ
      volumes:
      - name: volume-secret
        secret:
          secretName: user-pass-yaml # ํ•„๋“œ ๊ฐ’ ์„ค์ •
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: secretapp
  name: secretapp-svc
  namespace: default
spec:
  ports:
  - nodePort: 30900
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: secretapp
  type: NodePort

# ํ”„๋ผ์ด๋น— ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์‹œํฌ๋ฆฟ ์‚ฌ์šฉํ•˜๊ธฐ

  • ๋ณดํ†ต ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” ๋Œ€๋ถ€๋ถ„ ๊ณต๊ฐœ๋œ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉ
  • ํ”„๋ผ์ด๋น— ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ธ์ฆ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•œ๋ฐ ์ด ์ธ์ฆ ์ •๋ณด๋ฅผ ์‹œํฌ๋ฆฟ์— ์„ค์ •ํ•ด ์ €์žฅํ•œ ํ›„ ์‚ฌ์šฉ

# ์‹œํฌ๋ฆฟ์œผ๋กœ TLS ์ธ์ฆ์„œ๋ฅผ ์ €์žฅํ•ด ์‚ฌ์šฉํ•˜๊ธฐ

  • HTTPS ์ธ์ฆ์„œ๋ฅผ ์ €์žฅํ•˜๋Š” ์šฉ๋„๋กœ ์‹œํฌ๋ฆฟ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
$ kubectl create secret tls tlssecret --key tls.key --cert tls.crt

# ์‹œํฌ๋ฆฟ ๋ฐ์ดํ„ฐ ์šฉ๋Ÿ‰ ์ œํ•œ

  • ์‹œํฌ๋ฆฟ ๋ฐ์ดํ„ฐ๋Š” etcd์— ์•”ํ˜ธํ™”ํ•˜์ง€ ์•Š์€ ํ…์ŠคํŠธ๋กœ ์ €์žฅ๋˜๋Š”๋ฐ, ์ด๋•Œ ์‹œํฌ๋ฆฟ ๋ฐ์ดํ„ฐ์˜ ์šฉ๋Ÿ‰์ด ๋„ˆ๋ฌด ํฌ๋ฉด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์˜ kube-apiserver๋‚˜ kubelet์˜ ๋ฉ”๋ชจ๋ฆฌ ์šฉ๋Ÿ‰์„ ๋งŽ์ด ์ฐจ์ง€. ๊ฐœ๋ณ„ ์‹œํฌ๋ฆฟ ๋ฐ์ดํ„ฐ์˜ ์ตœ๋Œ€ ์šฉ๋Ÿ‰์€ 1MB

  • ๋ˆ„๊ตฐ๊ฐ€ etcd์— ์ง์ ‘ ์ ‘๊ทผํ•œ๋‹ค๋ฉด ์‹œํฌ๋ฆฟ ๋ฐ์ดํ„ฐ์˜ ๋‚ด์šฉ๋ฟ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธ ๊ฐ€๋Šฅ

  • ์ค‘์š”ํ•œ ์„œ๋น„์Šค์— ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋ฅผ ์‚ฌ์šฉ ์ค‘์ด๋ผ๋ฉด etcd ์ ‘๊ทผ์„ ์ œํ•œํ•˜๊ณ  ๊ธฐ๋ณธ์ ์œผ๋กœ etcd๋ฅผ ์‹คํ–‰ํ•  ๋•Œ etcd ๊ด€๋ จ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋Š” API ํ†ต์‹ ์— TLS ์ธ์ฆ์ด ์ ์šฉ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ธ์ฆ์„œ๊ฐ€ ์žˆ๋Š” ์‚ฌ์šฉ์ž๋งŒ etcd์— ์ ‘๊ทผํ•ด ๊ด€๋ จ ๋ช…๋ น์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

  • ๊ทธ ์™ธ์— etcd๊ฐ€ ์‹คํ–‰ ์ค‘์ธ ๋งˆ์Šคํ„ฐ ์ž์ฒด์— ์ง์ ‘ ์ ‘์†ํ•ด์„œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์œผ๋ ค๊ณ  ๋งˆ์Šคํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž๋“ค์„ ๊ณ„์ • ๊ธฐ๋ฐ˜์ด๋‚˜ IP ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด ๋“ฑ์˜ฌ ์ œํ•œํ•˜๋Š” ๋ฐฉ๋ฒ• ์กด์žฌ

  • etcd์— ์ €์žฅ๋˜๋Š” ์‹œํฌ๋ฆฟ ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™” ๊ฐ€๋Šฅ


# Referenses

  • ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ž…๋ฌธ - 90๊ฐ€์ง€ ์˜ˆ์ œ๋กœ ๋ฐฐ์šฐ๋Š” ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ ์ž๋™ํ™” ํ‘œ์ค€ / ๋™์–‘๋ถ์Šค
Last Updated: 8/12/2020, 1:33:42 PM